package com.music.note_android.ui.editor

import android.os.SystemClock
import android.util.Log
import java.util.concurrent.ConcurrentLinkedQueue

/**
 * 性能监控工具类
 * 用于监控画布绘制性能、内存使用情况等
 */
class PerformanceMonitor {
    
    companion object {
        private const val TAG = "PerformanceMonitor"
        private const val MAX_FRAME_SAMPLES = 60 // 保留最近60帧的数据
        private const val TARGET_FPS = 60
        private const val FRAME_TIME_THRESHOLD = 16.67f // 60fps对应的帧时间阈值(ms)
    }
    
    // 帧时间记录
    private val frameTimes = ConcurrentLinkedQueue<Long>()
    private var lastFrameTime = 0L
    private var frameCount = 0
    
    // 绘制性能统计
    private var totalDrawTime = 0L
    private var drawCallCount = 0
    private var strokeCount = 0
    
    // 内存使用统计
    private var peakMemoryUsage = 0L
    private var currentMemoryUsage = 0L
    
    // 性能警告回调
    var onPerformanceWarning: ((String) -> Unit)? = null
    
    /**
     * 开始帧时间测量
     */
    fun startFrame() {
        lastFrameTime = SystemClock.elapsedRealtimeNanos()
    }
    
    /**
     * 结束帧时间测量
     */
    fun endFrame() {
        val currentTime = SystemClock.elapsedRealtimeNanos()
        val frameTime = (currentTime - lastFrameTime) / 1_000_000 // 转换为毫秒
        
        // 记录帧时间
        frameTimes.offer(frameTime)
        
        // 保持队列大小
        while (frameTimes.size > MAX_FRAME_SAMPLES) {
            frameTimes.poll()
        }
        
        frameCount++
        
        // 检查性能警告
        if (frameTime > FRAME_TIME_THRESHOLD * 2) {
            onPerformanceWarning?.invoke("Frame time too high: ${frameTime}ms")
        }
    }
    
    /**
     * 记录绘制操作
     */
    fun recordDrawOperation(drawTime: Long, strokeCount: Int) {
        totalDrawTime += drawTime
        drawCallCount++
        this.strokeCount = strokeCount
    }
    
    /**
     * 更新内存使用情况
     */
    fun updateMemoryUsage() {
        val runtime = Runtime.getRuntime()
        currentMemoryUsage = runtime.totalMemory() - runtime.freeMemory()
        
        if (currentMemoryUsage > peakMemoryUsage) {
            peakMemoryUsage = currentMemoryUsage
        }
        
        // 检查内存警告
        val maxMemory = runtime.maxMemory()
        val memoryUsagePercent = (currentMemoryUsage.toFloat() / maxMemory) * 100
        
        if (memoryUsagePercent > 80) {
            onPerformanceWarning?.invoke("High memory usage: ${memoryUsagePercent.toInt()}%")
        }
    }
    
    /**
     * 获取平均FPS
     */
    fun getAverageFPS(): Float {
        if (frameTimes.isEmpty()) return 0f
        
        val averageFrameTime = frameTimes.average().toFloat()
        return if (averageFrameTime > 0) 1000f / averageFrameTime else 0f
    }
    
    /**
     * 获取最小FPS
     */
    fun getMinFPS(): Float {
        if (frameTimes.isEmpty()) return 0f
        
        val maxFrameTime = frameTimes.maxOrNull()?.toFloat() ?: 0f
        return if (maxFrameTime > 0) 1000f / maxFrameTime else 0f
    }
    
    /**
     * 获取平均绘制时间
     */
    fun getAverageDrawTime(): Float {
        return if (drawCallCount > 0) totalDrawTime.toFloat() / drawCallCount else 0f
    }
    
    /**
     * 获取内存使用情况
     */
    fun getMemoryInfo(): MemoryInfo {
        val runtime = Runtime.getRuntime()
        return MemoryInfo(
            current = currentMemoryUsage,
            peak = peakMemoryUsage,
            max = runtime.maxMemory(),
            free = runtime.freeMemory()
        )
    }
    
    /**
     * 获取性能报告
     */
    fun getPerformanceReport(): PerformanceReport {
        return PerformanceReport(
            averageFPS = getAverageFPS(),
            minFPS = getMinFPS(),
            frameCount = frameCount,
            averageDrawTime = getAverageDrawTime(),
            drawCallCount = drawCallCount,
            strokeCount = strokeCount,
            memoryInfo = getMemoryInfo()
        )
    }
    
    /**
     * 重置统计数据
     */
    fun reset() {
        frameTimes.clear()
        frameCount = 0
        totalDrawTime = 0L
        drawCallCount = 0
        strokeCount = 0
        peakMemoryUsage = 0L
    }
    
    /**
     * 打印性能报告
     */
    fun logPerformanceReport() {
        val report = getPerformanceReport()
        Log.d(TAG, "=== Performance Report ===")
        Log.d(TAG, "Average FPS: ${report.averageFPS}")
        Log.d(TAG, "Min FPS: ${report.minFPS}")
        Log.d(TAG, "Frame Count: ${report.frameCount}")
        Log.d(TAG, "Average Draw Time: ${report.averageDrawTime}ms")
        Log.d(TAG, "Draw Call Count: ${report.drawCallCount}")
        Log.d(TAG, "Stroke Count: ${report.strokeCount}")
        Log.d(TAG, "Memory Usage: ${report.memoryInfo.current / 1024 / 1024}MB")
        Log.d(TAG, "Peak Memory: ${report.memoryInfo.peak / 1024 / 1024}MB")
        Log.d(TAG, "=========================")
    }
    
    /**
     * 内存信息数据类
     */
    data class MemoryInfo(
        val current: Long,
        val peak: Long,
        val max: Long,
        val free: Long
    )
    
    /**
     * 性能报告数据类
     */
    data class PerformanceReport(
        val averageFPS: Float,
        val minFPS: Float,
        val frameCount: Int,
        val averageDrawTime: Float,
        val drawCallCount: Int,
        val strokeCount: Int,
        val memoryInfo: MemoryInfo
    )
}